GORM v2操作MySQL
多看官网!
在之前的项目中,都是使用gorm v1来操作MySQL(https://v1.gorm.io/)。
现在来学习使用一下gorm v2操作MySQL。
GORM 2.0 完全从零开始,引入了一些不兼容的 API 变更和许多改进。
简单记录gorm v2
在正式开始之前,先简单记录一下gorm v2的功能。
字段级权限控制
可导出的字段在使用 GORM 进行 CRUD 时拥有全部的权限,此外,GORM 允许您用标签控制字段级别的权限。这样您就可以让一个字段的权限是只读、只写、只创建、只更新或者被忽略
注意: 使用 GORM Migrator 创建表时,不会创建被忽略的字段
1 | type User struct { |
如果在自动迁移时忽略某个字段:
1 | Name string `gorm:"-:migration"` |
这里以后可能会比较常用。
字段标签
声明 model 时,tag 是可选的, tag 名大小写不敏感,但建议使用 camelCase
风格。
GORM 支持以下 tag:
标签名 | 说明 |
---|---|
column | 指定 db 列名 |
type | 列数据类型,推荐使用兼容性好的通用类型,例如:所有数据库都支持 bool、int、uint、float、string、time、bytes 并且可以和其他标签一起使用,例如:not null 、size , autoIncrement … 像 varbinary(8) 这样指定数据库数据类型也是支持的。在使用指定数据库数据类型时,它需要是完整的数据库数据类型,如:MEDIUMINT UNSIGNED not NULL AUTO_INCREMENT |
serializer | specifies serializer for how to serialize and deserialize data into db, e.g: serializer:json/gob/unixtime |
size | specifies column data size/length, e.g: size:256 |
primaryKey | specifies column as primary key |
unique | specifies column as unique |
default | specifies column default value |
precision | specifies column precision |
scale | specifies column scale |
not null | specifies column as NOT NULL |
autoIncrement | specifies column auto incrementable |
autoIncrementIncrement | auto increment step, controls the interval between successive column values |
embedded | embed the field |
embeddedPrefix | column name prefix for embedded fields |
autoCreateTime | track current time when creating, for int fields, it will track unix seconds, use value nano /milli to track unix nano/milli seconds, e.g: autoCreateTime:nano |
autoUpdateTime | track current time when creating/updating, for int fields, it will track unix seconds, use value nano /milli to track unix nano/milli seconds, e.g: autoUpdateTime:milli |
index | create index with options, use same name for multiple fields creates composite indexes, refer Indexes for details |
uniqueIndex | same as index , but create uniqued index |
check | creates check constraint, eg: check:age > 13 , refer Constraints |
<- | set field’s write permission, <-:create create-only field, <-:update update-only field, <-:false no write permission, <- create and update permission |
-> | set field’s read permission, ->:false no read permission |
- | ignore this field, - no read/write permission, -:migration no migrate permission, -:all no read/write/migrate permission |
comment | add comment for field when migration |
连接数据库
GORM 官方支持的数据库类型有: MySQL, PostgreSQL, SQlite, SQL Server。
这里我们以MySQL为例。
1 | package main |
- 带上
parseTime
参数,这样才能正确的处理time.Time
(更多参数) - 将
charset=utf8
更改为charset=utf8mb4
,这样才能支持完整的 UTF-8 编码(How to support full Unicode in MySQL databases)
MySQL 驱动程序提供了 一些高级配置 可以在初始化过程中使用,例如:
1
2
3
4
5
6
7
8 db, err := gorm.Open(mysql.New(mysql.Config{
DSN: "gorm:gorm@tcp(127.0.0.1:3306)/gorm?charset=utf8&parseTime=True&loc=Local", // DSN data source name
DefaultStringSize: 256, // string 类型字段的默认长度
DisableDatetimePrecision: true, // 禁用 datetime 精度,MySQL 5.6 之前的数据库不支持
DontSupportRenameIndex: true, // 重命名索引时采用删除并新建的方式,MySQL 5.7 之前的数据库和 MariaDB 不支持重命名索引
DontSupportRenameColumn: true, // 用 `change` 重命名列,MySQL 8 之前的数据库和 MariaDB 不支持重命名列
SkipInitializeWithVersion: false, // 根据当前 MySQL 版本自动配置
}), &gorm.Config{})
CRUD接口
具体使用多看看官网就好了。这里就给点代码简单实践一下。
关于gorm v2 logger LogLevel的设置,结合gin可以这么写:
1 | var mysqlLogger logger.Interface |
1 | package t_test |
总结gorm v2相较于v1的变化
更多的区别,参考:GORM 2.0 发布说明
import驱动不同
-
gorm v1 import:
1
2
3
4import (
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
) -
gorm v2 import:
1
2
3
4import (
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
数据库连接方式不同
以MySQL为例,gorm v1和gorm v2对数据库的连接有比较大的差异。
-
gorm v1:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23var MysqlDB *gorm.DB // 全局MysqlDB
func Init() {
//dsn := "user:pass@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
var builder strings.Builder
s := []string{config.MysqlUser, ":", config.MysqlPassword, "@tcp(", config.MysqlHost, ":", config.MysqlPort, ")/", config.MysqlName, "?charset=utf8mb4&parseTime=True&loc=Local"}
for _, str := range s {
builder.WriteString(str)
}
dsn := builder.String()
db, err := gorm.Open("mysql", dsn)
if err != nil {
log.Infoln(err)
}
db.LogMode(config.MysqlIsLog) // 开启 Logger, 以展示详细的日志
db.SingularTable(config.MysqlIsSingularTable) // 如果设置禁用表名复数形式属性为 true,`User` 的表名将是 `user`(因为gorm默认表名是复数)
db.DB().SetMaxIdleConns(config.MysqlMaxIdleConns) // 设置空闲连接池中的最大连接数
db.DB().SetMaxOpenConns(config.MysqlMaxOpenConns) // 设置数据库连接最大打开数。
db.DB().SetConnMaxLifetime(config.MysqlConnMaxLifetime) // 设置可重用连接的最长时间
// 自动迁移
db.AutoMigrate(&model.User{})
MysqlDB = db
} -
gorm v2:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38var MysqlDB *gorm.DB // 全局MysqlDB
func init() {
// mysqlLogger := logger.Default 默认LogLevel为Warn,一般我们开发调试时LogLevel设置为Info
mysqlLogger := logger.Default.LogMode(logger.Info)
dsn := "root:123456@tcp(127.0.0.1:3308)/test?charset=utf8mb4&parseTime=True&loc=Local"
db, err := gorm.Open(mysql.New(mysql.Config{
DSN: dsn, // DSN data source name
DefaultStringSize: 256, // string 类型字段的默认长度
DisableDatetimePrecision: true, // 禁用datetime精度,MySQL5.6之前的数据库不支
DontSupportRenameIndex: true, // 重命名索引时采用删除并新建的方式,MySQL5.7之前的数据库和MariaDB不支持重命名索引
DontSupportRenameColumn: true, // 用 `change` 重命名列,MySQL8之前的数据库和MariaDB不支持重命名列
SkipInitializeWithVersion: false, // 根据当前MySQL版本自动配置
}), &gorm.Config{
Logger: mysqlLogger,
NamingStrategy: schema.NamingStrategy{
SingularTable: true, // 表名不加s
//TablePrefix: "test_", // 指定表名前缀为test_
},
})
if err != nil {
logging.Info(err)
}
sqlDB, err := db.DB()
if err != nil {
logging.Info(err)
}
sqlDB.SetMaxIdleConns(20) // 设置空闲连接池中的最大连接数
sqlDB.SetMaxOpenConns(100) // 设置数据库连接最大打开数
sqlDB.SetConnMaxLifetime(time.Second * 30) // 设置可重用连接的最长时间
err = db.AutoMigrate(&User{}) // 自动迁移
if err != nil {
logging.Info(err)
}
MysqlDB = db
}
关于gorm v2 logger LogLevel的设置,结合gin可以这么写:
1 | var mysqlLogger logger.Interface |